package com.luck.emp.check.logic;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.springframework.jdbc.core.RowMapper;

import com.luck.emp.check.qry.CheckQry;
import com.luck.emp.common.SpGetDefaultPosiByWhCode;
import com.luck.emp.common.SpOrderNoTwo;
import com.luck.emp.common.SpWhOrderD;
import com.luck.emp.common.SpWhOrderM;
import com.luck.emp.entity.EmpTWhCheckD;
import com.luck.emp.entity.EmpTWhCheckM;
import com.luck.emp.report.vo.StorageVo;
import com.luck.pf.common.entity.UserBean;
import com.luck.pf.framework.dao.BaseJdbcDao;
import com.luck.pf.framework.logic.BaseLogic;
import com.luck.pf.util.CriteriaUtil;
import com.luck.pf.util.DateUtil;

/**
 * 说明
 * Copyright: Copyright (c) 2011
 * 深圳**科技
 * @author 
 * 
 */
public class CheckLogic extends BaseLogic implements ICheckLogic{
	private BaseJdbcDao jdbcDao;
	
	/**
	 * 查找分页信息
	 */
	public <T> T findCheckPage(CheckQry qry, Class<T> cls){
		Criteria criteria = baseDao.createCriteria(EmpTWhCheckM.class);		
		    CriteriaUtil.addEq(criteria, "checkCode", qry.getCheckCode());
		    CriteriaUtil.addEq(criteria, "whCode", qry.getWhCode());
		    CriteriaUtil.addEq(criteria, "status", qry.getStatus());
		Order order=Order.desc("createDate");
		criteria.addOrder(order);

		if(qry.getOrgId() != null)
			CriteriaUtil.addEq(criteria, "deptId", qry.getOrgId());
		else{
			criteria.createAlias("dept", "d");
			filterData(criteria, qry.getUserInfo(), "d", null);
		}
		if (cls.getName().equals("java.util.List")) {
			return (T) criteria.list();
		} else {
			return (T) baseDao.pagedQuery(criteria, qry.getPageNo(),qry.getPageSize());
		}
	}	
	public List<EmpTWhCheckD> findChecksByCheckCode(String checkCode){
		return super.baseDao.find(" FROM EmpTWhCheckD WHERE checkCode=? order by productCode", checkCode);
	}
	
	public String saveCheck(UserBean userBean, EmpTWhCheckM entity,String[] productCodes,String[] planQtys) throws Exception{
		StringBuffer bf = new StringBuffer();
		SpGetDefaultPosiByWhCode sdp = new SpGetDefaultPosiByWhCode(this.jdbcDao.getJdbcTemplate());
		String posi = sdp.execute(entity.getWhCode(),"2");
		//String posi = "111";
		SpOrderNoTwo sp = new SpOrderNoTwo(this.jdbcDao.getJdbcTemplate());
		String checkCode = sp.execute(userBean.getDept().getDeptCode(), "PD");
		
		entity.setCheckCode(checkCode);
		entity.setCreateDate(DateUtil.getDate());
		entity.setCreateUser(userBean.getUser());
		entity.setDeptId(userBean.getDeptId());
		entity.setModiUser(userBean.getUser());
		entity.setModiDate(DateUtil.getDate());
		entity.setStatus("1");
		entity.setTarget("1");
		//entity.setCheckType("1");
		super.save(entity);
		for(int i=0; i < productCodes.length; i++){
			EmpTWhCheckD d = new EmpTWhCheckD();
			d.setCheckCode(checkCode);
			//d.setConfirmQty(Long.parseLong(confirmQtys[i]));
			d.setPlanQty(Long.parseLong(planQtys[i]));
			d.setPosiCode(posi);
			d.setProductCode(productCodes[i]);
			//d.setQtyDiff(d.getPlanQty()-d.getConfirmQty());
			//d.setVerifyMemo(notes[i]);
			d.setWhCode(entity.getWhCode());
			save(d);
		}
		return bf.toString();
	}
	/**
	 * 保存反馈信息
	 **/
	public String saveCheckFeedback(UserBean userBean, EmpTWhCheckM entity,String[] detailIds, String[] confirmQtys,String[] notes) throws Exception{
		StringBuffer bf = new StringBuffer();
		entity = super.get(EmpTWhCheckM.class, entity.getCheckCode());
		entity.setStatus("2");//已反馈
		entity.setModiDate(DateUtil.getDate());
		entity.setModiUser(userBean.getUser());
		super.save(entity);
		for(int i=0; i < detailIds.length; i++){
			EmpTWhCheckD d = super.get(EmpTWhCheckD.class, Long.parseLong(detailIds[i]));
			d.setConfirmQty(Long.parseLong(confirmQtys[i]));
			d.setQtyDiff(d.getPlanQty()-d.getConfirmQty());//<0则表示是要增加库存，盘点入库,>0则为盘点出库，减少库存
			d.setVerifyMemo(notes[i]);
			save(d);
			if(d.getQtyDiff()!=null && d.getQtyDiff()!=0){//判断一定要写备注
				if(StringUtils.isBlank(d.getVerifyMemo()))
					bf.append("<br>库存发生变化，必须填写原因!");
			}
		}
		if(StringUtils.isNotBlank(bf.toString()))
			throw new Exception(bf.toString());
		//处理明细数据
		return null;
	}
	public String saveAudit(UserBean userBean, EmpTWhCheckM check) throws Exception{
		StringBuffer bf = new StringBuffer();
		EmpTWhCheckM entity = get(EmpTWhCheckM.class, check.getCheckCode());
		List<EmpTWhCheckD> details = findChecksByCheckCode(check.getCheckCode());
		entity.setStatus(check.getStatus());
		entity.setAuditDate(DateUtil.getDate());
		entity.setAuditor(userBean.getUser());
		save(entity);
		if(!entity.getStatus().equals("3"))
			return bf.toString();
		//处理盘点出库
		List<EmpTWhCheckD> outs = new ArrayList<EmpTWhCheckD>();
		List<EmpTWhCheckD> ins = new ArrayList<EmpTWhCheckD>();
		for(EmpTWhCheckD info:details){//<0则表示是要增加库存，盘点入库,>0则为盘点出库，减少库存
			if(info.getQtyDiff()<0)
				ins.add(info);
			if(info.getQtyDiff()>0)
				outs.add(info);
		}
		
		if(ins != null && !ins.isEmpty()){//处理入库
			//处理出入库主表
			String billType = "18";//盘点单
			String ioType = "15";//盘盈入库
			SpWhOrderM sp = new SpWhOrderM(this.jdbcDao.getJdbcTemplate());
			String orderCode = sp.execute(billType, 20L, entity.getCheckCode(),entity.getWhCode(), null, 
					null, null, null, "盘盈入库", entity.getModiUser().getId(), ioType, null, null, null);
			//处理入库单明细
			SpWhOrderD spd = new SpWhOrderD(this.jdbcDao.getJdbcTemplate());
			for(EmpTWhCheckD in:ins){
				spd.execute(orderCode, in.getProductCode(), -in.getQtyDiff(), 0, 0, entity.getModiUser().getId(), DateUtil.dateToString(entity.getModiDate(), DateUtil.patternF));				
			}
		}
		if(outs != null && !outs.isEmpty()){//处理出库
			//处理出入库主表
			String billType = "18";//盘点单
			String ioType = "46";//盘亏出库
			SpWhOrderM sp = new SpWhOrderM(this.jdbcDao.getJdbcTemplate());
			String orderCode = sp.execute(billType, 20L, entity.getCheckCode(),entity.getWhCode(), null, 
					null, null, null, "盘亏出库", entity.getModiUser().getId(), ioType, null, null, null);
			//处理入库单明细
			SpWhOrderD spd = new SpWhOrderD(this.jdbcDao.getJdbcTemplate());
			for(EmpTWhCheckD out:outs){
				spd.execute(orderCode, out.getProductCode(), out.getQtyDiff(), 0, 0, entity.getModiUser().getId(), DateUtil.dateToString(entity.getModiDate(), DateUtil.patternF));				
			}
		}
		
		
		return bf.toString();
	}
	/**
	 * 删除
	 */
	public String deleteCheck(UserBean userBean, EmpTWhCheckM entity) throws Exception{
		StringBuffer bf = new StringBuffer();
		if(!entity.getDeptId().equals(userBean.getDeptId()))
			bf.append("<br>不属于你所在机构");
		if(!entity.getStatus().equals("1"))
			bf.append("<br>不是新建状态");
		if(StringUtils.isNotBlank(bf.toString()))
			throw new Exception(bf.toString());
		super.delete(entity);
		super.baseDao.getHibernateTemplate().deleteAll(findChecksByCheckCode(entity.getCheckCode()));
		return null;
	}
	public  <T> T findCheckProductPage(CheckQry qry, Class<T> cls){
		StringBuffer sql = new StringBuffer();
		Map params = new HashMap();
		sql.append("SELECT D.DEPT_NAME  DEPTNAME, ");
		sql.append("       D.ID         DEPTID,         ");
		sql.append("       WH.V_WH_NAME WHNAME, ");
		sql.append("       B.V_WH_CODE      WHCODE, ");
		sql.append("       P.V_NAME         PRODUCTNAME, ");
		sql.append("       B.V_PRODUCT_CODE PRODUCTCODE, ");
		sql.append("       P.V_PROD_BARCODE PRODBARCODE, ");
		sql.append("       P.V_SKU          SKU, ");
		sql.append("       B.QTY  qty , sale.N_PRICE price, sale.N_LOW_PRICE lowPrice, ");
		sql.append("       PARAMS.PARAM_NAME MEASUNIT");
		sql.append("  FROM (SELECT T.V_WH_CODE, T.V_PRODUCT_CODE, NVL(SUM(T.N_QTY), 0) QTY ");
		sql.append("          FROM EMP_T_WH_BALANCE T ");
		sql.append("         GROUP BY T.V_WH_CODE, T.V_PRODUCT_CODE) B, ");
		sql.append("       EMP_T_WAREHOUSE WH, ");
		sql.append("       SYS_DEPARTMENT D, ");
		sql.append("       EMP_T_PROD_BASE P,SYS_PARAMS PARAMS, EMP_T_PROD_SALE sale");
		sql.append(" WHERE B.V_WH_CODE = WH.V_WH_CODE ");
		sql.append("   AND WH.N_DEPT_ID = D.ID ");
		sql.append("   AND B.V_PRODUCT_CODE = P.V_PRODUCT_CODE");
		sql.append("   AND B.V_PRODUCT_CODE = sale.V_PRODUCT_CODE");
		sql.append(" AND PARAMS.PARAM_CODE = 'p_meas_unit' ");
		sql.append(" AND P.V_MEAS_UNIT = PARAMS.PARAM_VALUE ");
		if(StringUtils.isNotBlank(qry.getProductName()))
			sql.append(" and p.v_name like '%"+qry.getProductName()+"%' ");
		if(StringUtils.isNotBlank(qry.getProductCode())){
			sql.append(" and b.V_PRODUCT_CODE like :productCode ");
			params.put("productCode", "%"+qry.getProductCode()+"%");
		}
		if(StringUtils.isNotBlank(qry.getOperateType()) && qry.getOperateType().equals("barcode")){
			sql.append(" and p.V_PROD_BARCODE ='"+qry.getProdBarcode()+"'");
		}else if(StringUtils.isNotBlank(qry.getProdBarcode())){
			sql.append(" and p.V_PROD_BARCODE like :proBarcode ");
			params.put("proBarcode", "%"+qry.getProdBarcode()+"%");
		}
		if(qry.getKindId() != null){
			sql.append(" and p.N_PROD_KIND =:kindId");
			params.put("kindId", qry.getKindId());
		}
		if(StringUtils.isNotBlank(qry.getStatus())){
			sql.append(" and p.v_status =:vstatus ");
			params.put("vstatus", qry.getStatus());
		}
		if(StringUtils.isNotBlank(qry.getSku())){
			sql.append(" and p.V_SKU like :sku ");
			params.put("sku", "%"+qry.getSku()+"%");
		}
		if(StringUtils.isNotBlank(qry.getWhCode())){
			sql.append(" and b.V_WH_CODE =:whCode ");
			params.put("whCode", qry.getWhCode());
		}

		sql.append(" and wh.N_DEPT_ID =:deptId ");
		params.put("deptId", qry.getUserInfo().getOrgId());

		//System.out.println(sql.toString());
		if (cls.getName().equals("java.util.List")) {
			return (T)  this.jdbcDao.queryForList(sql.toString(), params,storageRw);
		} else {
			return (T) jdbcDao.queryForPage(sql.toString(), params, qry.getPageNo(),qry.getPageSize(), storageRw);
		}
	}
	private static final StorageRw storageRw = new StorageRw();

	private static final class StorageRw implements RowMapper {
		public Object mapRow(ResultSet rs, int rownum) throws SQLException {
			StorageVo vo = new StorageVo();
			vo.setIndex(rownum + 1);
			vo.setCurrentQry(rs.getLong("qty"));
			vo.setDeptId(rs.getLong("deptId"));
			vo.setDeptName(rs.getString("deptName"));
			vo.setProdBarcode(rs.getString("PRODBARCODE"));
			vo.setProductCode(rs.getString("productCode"));
			vo.setProductName(rs.getString("productName"));
			vo.setSku(rs.getString("sku"));
			vo.setWhCode(rs.getString("whCode"));
			vo.setWhName(rs.getString("whName"));
			vo.setMeasUnit(rs.getString("MEASUNIT"));
			vo.setPrice(rs.getDouble("price"));
			vo.setLowPrice(rs.getDouble("lowPrice"));
			//vo.setNote(rs.getString("V_NOTE"));
			//vo.setExDId(rs.getLong("N_EX_D_ID"));
			return vo;
		}
	}
	public BaseJdbcDao getJdbcDao() {
		return jdbcDao;
	}

	public void setJdbcDao(BaseJdbcDao jdbcDao) {
		this.jdbcDao = jdbcDao;
	}

}